#include "Common/Utility/JsonUtility.h"
#include "Common/Utility/TimeUtility.h"
#include "base/core/com_define.h"

using namespace rapidjson;


const char* GetJsonStringValue(const rapidjson::Document& docjson, const char* key) 
{
    MMO_ASSERT(key != nullptr);

    Value::ConstMemberIterator  it = docjson.FindMember(key);
    if (it == docjson.MemberEnd()) 
	{
        return nullptr;
    }
    if (!it->value.IsString()) 
	{
        return nullptr;
    }
    return it->value.GetString();
}

bool GetJsonInt32Value(const rapidjson::Document& docjson, const char* key, int32_t& val) 
{
    MMO_ASSERT(key != nullptr);

    Value::ConstMemberIterator  it = docjson.FindMember(key);
    if (it == docjson.MemberEnd()) 
	{
        return false;
    }
    if (it->value.IsString()) 
	{
        val = atoi(it->value.GetString());
        return true;
    }
    if (it->value.IsNumber() && !it->value.IsDouble()) 
	{
        val = it->value.GetInt();
        return true;
    }
    return false;
}

bool GetJsonUInt32Value(const rapidjson::Document& docjson, const char* key, uint32_t& val) 
{
    MMO_ASSERT(key != nullptr);

    Value::ConstMemberIterator  it = docjson.FindMember(key);
    if (it == docjson.MemberEnd()) 
	{
        return false;
    }
    if (it->value.IsString()) 
	{
        val = atoi(it->value.GetString());
        return true;
    }
    if (it->value.IsNumber() && !it->value.IsDouble()) 
	{
        val = it->value.GetUint();
        return true;
    }
    return false;
}

bool GetJsonInt64Value(const rapidjson::Document& docjson, const char* key, int64_t& val) 
{
    MMO_ASSERT(key != nullptr);

    Value::ConstMemberIterator  it = docjson.FindMember(key);
    if (it == docjson.MemberEnd()) 
	{
        return false;
    }
    if (it->value.IsString()) 
	{
        val = (int64_t)strtoull(it->value.GetString(), nullptr, 10);
        return true;
    }
    if (it->value.IsNumber() && !it->value.IsDouble()) 
	{
        val = it->value.GetInt64();
        return true;
    }
    return false;
}

bool GetJsonUInt64Value(const rapidjson::Document& docjson, const char* key, uint64_t& val) 
{
    MMO_ASSERT(key != nullptr);

    Value::ConstMemberIterator  it = docjson.FindMember(key);
    if (it == docjson.MemberEnd()) 
	{
        return false;
    }
    if (it->value.IsString()) 
	{
        val = (uint64_t)strtoull(it->value.GetString(), nullptr, 10);
        return true;
    }
    if (it->value.IsNumber() && !it->value.IsDouble()) 
	{
        val = it->value.GetUint64();
        return true;
    }
    return false;
}

bool GetJsonFloatValue(const rapidjson::Document& docjson, const char* key, float& val) 
{
    MMO_ASSERT(key != nullptr);

    Value::ConstMemberIterator  it = docjson.FindMember(key);
    if (it == docjson.MemberEnd()) 
	{
        return false;
    }
    if (it->value.IsNumber()) 
	{
        val = (float)it->value.GetDouble();
        return true;
    }
    return false;
}

bool GetJsonDoubleValue(const rapidjson::Document& docjson, const char* key, double& val) 
{
    MMO_ASSERT(key != nullptr);

    Value::ConstMemberIterator  it = docjson.FindMember(key);
    if (it == docjson.MemberEnd()) 
	{
        return false;
    }
    if (it->value.IsNumber()) 
	{
        val = it->value.GetDouble();
        return true;
    }
    return false;
}

bool GetJsonBoolValue(const rapidjson::Document& docjson, const char* key, bool& val) 
{
    MMO_ASSERT(key != nullptr);

    Value::ConstMemberIterator  it = docjson.FindMember(key);
    if (it == docjson.MemberEnd()) 
	{
        return false;
    }
    if (it->value.IsBool()) 
	{
        val = it->value.GetBool();
        return true;
    }
    if (it->value.IsNumber() && !it->value.IsDouble()) 
	{
        int _val = it->value.GetInt();
        val = (_val != 0);
        return true;
    }
    if (it->value.IsString()) 
	{
        const char* str = it->value.GetString();
        if (strcmp(str, "true") == 0) 
		{
            val = true;
            return true;
        }
        else if (strcmp(str, "false") == 0) 
		{
            val = false;
            return true;
        }
    }
    return false;
}

bool GetJsonInt32Value(const rapidjson::Document& docjson, const char* key, int32_t defaultVal, int32_t& val) 
{
    MMO_ASSERT(key != nullptr);
    val = defaultVal;
    return GetJsonInt32Value(docjson, key, val);
}

bool GetJsonUInt32Value(const rapidjson::Document& docjson, const char* key, uint32_t dafaultVal, uint32_t& val) 
{
    MMO_ASSERT(key != nullptr);
    val = dafaultVal;
    return GetJsonUInt32Value(docjson, key, val);
}

bool GetJsonBoolValue(const rapidjson::Document& docjson, const char* key, bool defaultVal, bool& val) 
{
    MMO_ASSERT(key != nullptr);
    val = defaultVal;
    return GetJsonBoolValue(docjson, key, val);
}

bool GetJsonTimeStampToUnixSec(const rapidjson::Document& docjson, const char* key, uint64_t& val) 
{
    MMO_ASSERT(key != nullptr);
    Value::ConstMemberIterator  it = docjson.FindMember(key);
    if (it == docjson.MemberEnd()) 
	{
        return false;
    }
    if (!it->value.IsString()) 
	{
        return false;
    }
    val = TimeUtility::LocalTimeStampToUnixSec("%d-%d-%d %d:%d:%d", it->value.GetString());
    return true;
}

const char* GetJsonStringValue(const rapidjson::Value& docjson, const char* key) 
{
    MMO_ASSERT(key != nullptr);
    Value::ConstMemberIterator  it = docjson.FindMember(key);
    if (it == docjson.MemberEnd()) 
	{
        return nullptr;
    }
    if (!it->value.IsString()) 
	{
        return nullptr;
    }
    return it->value.GetString();
}

bool GetJsonInt32Value(const rapidjson::Value& docjson, const char* key, int32_t& val) 
{
    MMO_ASSERT(key != nullptr);
    Value::ConstMemberIterator  it = docjson.FindMember(key);
    if (it == docjson.MemberEnd()) 
	{
        return false;
    }
    if (it->value.IsString()) 
	{
        val = atoi(it->value.GetString());
        return true;
    }
    if (it->value.IsNumber() && !it->value.IsDouble()) 
	{
        val = it->value.GetInt();
        return true;
    }
    return false;
}

bool GetJsonUInt32Value(const rapidjson::Value& docjson, const char* key, uint32_t& val) 
{
    MMO_ASSERT(key != nullptr);
    Value::ConstMemberIterator  it = docjson.FindMember(key);
    if (it == docjson.MemberEnd()) 
	{
        return false;
    }
    if (it->value.IsString()) 
	{
        val = atoi(it->value.GetString());
        return true;
    }
    if (it->value.IsNumber() && !it->value.IsDouble()) 
	{
        val = it->value.GetUint();
        return true;
    }
    return false;
}

bool GetJsonBoolValue(const rapidjson::Value& docjson, const char* key, bool& val) 
{
    MMO_ASSERT(key != nullptr);
    Value::ConstMemberIterator  it = docjson.FindMember(key);
    if (it == docjson.MemberEnd()) 
	{
        return false;
    }
    if (it->value.IsBool()) 
	{
        val = it->value.GetBool();
        return true;
    }
    if (it->value.IsNumber() && !it->value.IsDouble()) 
	{
        int _val = it->value.GetInt();
        val = (_val != 0);
        return true;
    }
    if (it->value.IsString()) 
	{
        const char* str = it->value.GetString();
        if (strcmp(str, "true") == 0) 
		{
            val = true;
            return true;
        }
        else if (strcmp(str, "false") == 0) 
		{
            val = false;
            return true;
        }
    }
    return false;
}

bool GetJsonInt32Value(const rapidjson::Value& docjson, const char* key, int32_t defaultVal, int32_t& val) 
{
    MMO_ASSERT(key != nullptr);
    val = defaultVal;
    return GetJsonInt32Value(docjson, key, val);
}

bool GetJsonBoolValue(const rapidjson::Value& docjson, const char* key, bool defaultVal, bool& val) 
{
    MMO_ASSERT(key != nullptr);
    val = defaultVal;
    return GetJsonBoolValue(docjson, key, val);
}

JsonArray::JsonArray(rapidjson::Document* doc) 
{
    m_doc = doc;
    m_value = new rapidjson::Value(rapidjson::kArrayType);
    MMO_ASSERT(m_value != nullptr);
}

JsonArray::~JsonArray() 
{
    MMO_DELETE(m_value);
}

bool JsonArray::PushString(const char* val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kStringType);
    _val.SetString(val, allocator);
    m_value->PushBack(_val, allocator);
    return true;
}

bool JsonArray::PushString(const std::string& val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kStringType);
    _val.SetString(val.c_str(), allocator);
    m_value->PushBack(_val, allocator);
    return true;
}

bool JsonArray::PushInt32(int32_t val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kNumberType);
    _val.SetInt(val);
    m_value->PushBack(_val, allocator);
    return true;
}

bool JsonArray::PushUInt32(uint32_t val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kNumberType);
    _val.SetUint(val);
    m_value->PushBack(_val, allocator);
    return true;
}

bool JsonArray::PushInt64(int64_t val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kNumberType);
    _val.SetInt64(val);
    m_value->PushBack(_val, allocator);
    return true;
}

bool JsonArray::PushUInt64(uint64_t val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kNumberType);
    _val.SetUint64(val);
    m_value->PushBack(_val, allocator);
    return true;
}

bool JsonArray::PushFloat(float val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kNumberType);
    _val.SetDouble(val);
    m_value->PushBack(_val, allocator);
    return true;
}

bool JsonArray::PushDouble(double val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kNumberType);
    _val.SetDouble(val);
    m_value->PushBack(_val, allocator);
    return true;
}

bool JsonArray::PushBool(bool val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kNumberType);
    _val.SetBool(val);
    m_value->PushBack(_val, allocator);
    return true;
}

bool JsonArray::PushArray(int32_t array[], size_t size) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kNumberType);
    for (size_t i = 0; i < size; ++i) 
	{
        _val.SetInt(array[i]);
        m_value->PushBack(_val, allocator);
    }
    return true;
}

bool JsonArray::PushArray(uint32_t array[], size_t size) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kNumberType);
    for (size_t i = 0; i < size; ++i) 
	{
        _val.SetUint(array[i]);
        m_value->PushBack(_val, allocator);
    }
    return true;
}

bool JsonArray::PushArray(char* array[], size_t size) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kStringType);
    for (size_t i = 0; i < size; ++i) 
	{
        if (array[i] != nullptr) 
		{
            _val.SetString(array[i], allocator);
            m_value->PushBack(_val, allocator);
        }
    }
    return true;
}

bool JsonArray::PushArray(const JsonArray& val) 
{
    MMO_ASSERT(m_value != nullptr);
    MMO_ASSERT(val.m_value != nullptr);
    MMO_ASSERT(m_doc == val.m_doc);
    MMO_ASSERT(&val != this);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    m_value->PushBack(*val.m_value, allocator);
    return true;
}

bool JsonArray::PushVector(const std::vector<int32_t>& val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kNumberType);
    for (size_t i = 0; i < val.size(); ++i) 
	{
        _val.SetInt(val[i]);
        m_value->PushBack(_val, allocator);
    }
    return true;
}

bool JsonArray::PushVector(const std::vector<uint32_t>& val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kNumberType);
    for (size_t i = 0; i < val.size(); ++i) 
	{
        _val.SetUint(val[i]);
        m_value->PushBack(_val, allocator);
    }
    return true;
}

bool JsonArray::PushVector(const std::vector<std::string>& val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _val(rapidjson::kStringType);
    for (size_t i = 0; i < val.size(); ++i) 
	{
        _val.SetString(val[i].c_str(), allocator);
        m_value->PushBack(_val, allocator);
    }
    return true;
}

bool JsonArray::PushObject(const JsonObject& obj) 
{
    MMO_ASSERT(m_value != nullptr);
    MMO_ASSERT(obj.m_value != nullptr);
    MMO_ASSERT(obj.m_doc == m_doc);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    m_value->PushBack(*obj.m_value, allocator);
    return true;
}

bool JsonArray::ToString(std::string& str) const
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    m_value->Accept(writer);
    str = buffer.GetString();
    return true;
}

bool JsonArray::ToString(char* buf, size_t len) const
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    m_value->Accept(writer);
    size_t _len = buffer.GetSize();
    if (len <= _len) 
	{
        return false;
    }
    memcpy(buf, buffer.GetString(), _len);
    buf[_len] = '\0';
    return true;
}

std::string JsonArray::ToString() const 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    m_value->Accept(writer);
    return buffer.GetString();
}

uint32_t JsonArray::Size() const 
{
    MMO_ASSERT(m_value != nullptr);
    return m_value->Size();
}

rapidjson::Document* JsonArray::GetDoc() 
{
    return m_doc;
}

JsonObject::JsonObject(rapidjson::Document* doc) 
{
    m_doc = doc;
    m_value = new rapidjson::Value(rapidjson::kObjectType);
    MMO_ASSERT(m_value != nullptr);
}

JsonObject::~JsonObject() 
{
    MMO_DELETE(m_value);
}

bool JsonObject::AddString(const char* key, const char* val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    rapidjson::Value _val(rapidjson::kStringType);
    _key.SetString(key, allocator);
    _val.SetString(val, allocator);
    m_value->AddMember(_key, _val, allocator);
    return true;
}

bool JsonObject::AddString(const char* key, const std::string& val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    rapidjson::Value _val(rapidjson::kStringType);
    _key.SetString(key, allocator);
    _val.SetString(val.c_str(), allocator);
    m_value->AddMember(_key, _val, allocator);
    return true;
}

bool JsonObject::AddInt32(const char* key, int32_t val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    rapidjson::Value _val(rapidjson::kNumberType);
    _key.SetString(key, allocator);
    _val.SetInt(val);
    m_value->AddMember(_key, _val, allocator);
    return true;
}

bool JsonObject::AddUInt32(const char* key, uint32_t val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    rapidjson::Value _val(rapidjson::kNumberType);
    _key.SetString(key, allocator);
    _val.SetUint(val);
    m_value->AddMember(_key, _val, allocator);
    return true;
}

bool JsonObject::AddInt64(const char* key, int64_t val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    rapidjson::Value _val(rapidjson::kNumberType);
    _key.SetString(key, allocator);
    _val.SetInt64(val);
    m_value->AddMember(_key, _val, allocator);
    return true;
}

bool JsonObject::AddUInt64(const char* key, uint64_t val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    rapidjson::Value _val(rapidjson::kNumberType);
    _key.SetString(key, allocator);
    _val.SetUint64(val);
    m_value->AddMember(_key, _val, allocator);
    return true;
}

bool JsonObject::AddFloat(const char* key, float val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    rapidjson::Value _val(rapidjson::kNumberType);
    _key.SetString(key, allocator);
    _val.SetDouble(val);
    m_value->AddMember(_key, _val, allocator);
    return true;
}

bool JsonObject::AddDouble(const char* key, double val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    rapidjson::Value _val(rapidjson::kNumberType);
    _key.SetString(key, allocator);
    _val.SetDouble(val);
    m_value->AddMember(_key, _val, allocator);
    return true;
}

bool JsonObject::AddBool(const char* key, bool val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    rapidjson::Value _val(rapidjson::kNumberType);
    _key.SetString(key, allocator);
    _val.SetBool(val);
    m_value->AddMember(_key, _val, allocator);
    return true;
}

bool JsonObject::AddArray(const char* key, const JsonArray& array) 
{
    MMO_ASSERT(m_value != nullptr);
    MMO_ASSERT(array.m_value != nullptr);
    MMO_ASSERT(array.m_doc == m_doc);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    _key.SetString(key, allocator);
    m_value->AddMember(_key, *(array.m_value), allocator);
    return true;
}

bool JsonObject::AddObject(const char* key, const JsonObject& obj) 
{
    MMO_ASSERT(m_value != nullptr);
    MMO_ASSERT(obj.m_value != nullptr);
    MMO_ASSERT(obj.m_doc == m_doc);
    MMO_ASSERT(&obj != this);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    _key.SetString(key, allocator);
    m_value->AddMember(_key, *(obj.m_value), allocator);
    return true;
}

bool JsonObject::AddMap(const std::map<std::string, int32_t>& val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    rapidjson::Value _val(rapidjson::kNumberType);
    for (auto it = val.begin(); it != val.end(); ++it) 
	{
        _key.SetString(it->first.c_str(), allocator);
        _val.SetInt(it->second);
        m_value->AddMember(_key, _val, allocator);
    }
    return true;
}

bool JsonObject::AddMap(const std::map<std::string, uint32_t>& val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    rapidjson::Value _val(rapidjson::kNumberType);
    for (auto it = val.begin(); it != val.end(); ++it) 
	{
        _key.SetString(it->first.c_str(), allocator);
        _val.SetUint(it->second);
        m_value->AddMember(_key, _val, allocator);
    }
    return true;
}

bool JsonObject::AddMap(const std::map<std::string, std::string>& val) 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::Document::AllocatorType& allocator = m_doc->GetAllocator();
    rapidjson::Value _key(rapidjson::kStringType);
    rapidjson::Value _val(rapidjson::kStringType);
    for (auto it = val.begin(); it != val.end(); ++it) 
	{
        _key.SetString(it->first.c_str(), allocator);
        _val.SetString(it->second.c_str(), allocator);
        m_value->AddMember(_key, _val, allocator);
    }
    return true;
}

bool JsonObject::ToString(std::string& str) const 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    m_value->Accept(writer);
    str = buffer.GetString();
    return true;
}

bool JsonObject::ToString(char* buf, size_t len) const 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    m_value->Accept(writer);
    size_t _len = buffer.GetSize();
    if (len <= _len) 
	{
        return false;
    }
    memcpy(buf, buffer.GetString(), _len);
    buf[_len] = '\0';
    return true;
}

std::string JsonObject::ToString() const 
{
    MMO_ASSERT(m_value != nullptr);
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    m_value->Accept(writer);
    return buffer.GetString();
}

rapidjson::Document* JsonObject::GetDoc() 
{
    return m_doc;
}

JsonRoot::JsonRoot() : JsonObject(nullptr) 
{
    m_doc = &m_sdoc;
}

JsonRoot::~JsonRoot() 
{
    m_doc = nullptr;
}
